/***
 * @Author: xushenghao
 * @Date: 2023-03-20 19:27:47
 * @LastEditors: xushenghao
 * @LastEditTime: 2023-03-30 00:29:48
 * @FilePath: \hart\hart\inc\hart_frame.h
 * @Description:
 * @email:
 * @Copyright (c) 2023 by xushenghao, All Rights Reserved.
 */

#ifndef __HART_FRAME_H_
#define __HART_FRAME_H_
#include "lib.h"
#include "./hart_common_tables_specification.h"
#include "./hart_frame_user.h"
/*
    FALSH :     bank1 0x0800 0000 - 0x0800 FFFF
                bank2 0x0801 0000 - 0x0801 FFFF
    EEPROM :    bank1 0x0808 0000 - 0x0808 0BFF
                bank2 0x0808 0C00 - 0x0808 17FF
    6 Kbytes of data EEPROM with ECC
    在写入EEPROM 的时候，如果发生了串口中断，那么就很容易出问题
*/

// HART缓存区生命周期
#define KEY_CACHE_TIME_MS (30 * 1000)
#define HART_INTERNAL (3U)
// 内部调试开关，本地调试使用，上线后请根据需要设置
#define HART_PROTOCOL_VERSION_SUPPORT_COMMAND 1U // hart版本指令检查 1:打开 0:关闭

#define HART_RESPONSE_MAX_LEN 254U // HART响应数据最大长度

#define HART_PROTOCOL_VERSION_5 5U // hart协议版本号5.0
#define HART_PROTOCOL_VERSION_7 7U // hart协议版本号7.2

#define HART_SHORT_ADDRESS 0x00                                                                    // 默认短地址
#define HART_LONG_ADDRESS (((uint64_t)(EXTENDED_DEVICE_TYPE_LAPOOL) << 24) + (uint64_t)(0x000000)) // 默认长地址

// 从机参数宏定义
#define HART_PREAMBLE 0xFF                                      // 前导符
#define HART_PREAMBLE_DEFAULT_LEN 8U                            // 前导符默认长度
#define HART_MASTER_ADDRESS 0x01                                // 主设备地址
#define HART_BURST_FRAME 0x01                                   // 突发帧
#define HART_STX_FRAME 0x02                                     // 请求帧, 主->从
#define HART_ACK_FRAME 0x06                                     // 应答帧, 从->主
#define HART_DELIMITER_TYPE_SHORT 0x00                          // 短帧类型
#define HART_DELIMITER_TYPE_LONG 0x01                           // 长帧类型
#define HART_SHORT_ADDRESS_LEN 1U                               // 短帧格式地址长度
#define HART_LONG_ADDRESS_LEN 5U                                // 长帧格式地址长度
#define HART_SOLT_DEVICE_VARIABLE_LEN 8U                        // 插槽设备变量长度
#define HART_DEVICE_VARIABLE_LEN 8                              // 设备变量长度
#define HART_ANALOG_CHANNEL_LEN ANALOG_CHANNEL_NUMBER_CODES_MAX // 模拟通道长度
#define HART_INVALID_VALUE 0x7FA00000                           // 无效值
#define HART_SQUAWK_CONTROL_ONCE_TIME 0x02                      // 一次性响应时间(秒)
#define TREND_CONFIGURATIONS_LEN 1U                             // 趋势配置长度
#define TREND_VALUES_LEN 12U                                    // 趋势值长度
#define SYNCHRONIZATION_OPERATION_LEN 1U                        // 同步操作长度
#define SYNCHRONIZATION_OPERATION_COMMAND_DATA_LEN 4U           // 同步操作命令数据长度
#define BURST_MESSAGE_LEN 1U                                    // 突发消息长度
#define BURST_MESSAGE_UPDATE_TIME_MAX 3600U                     // 突发消息更新时间最大值

// 主机参数宏定义
#define HART_IO_MAXIMUM_NUMBER_CARDS 1U           // 最大卡数
#define HART_IO_MAXIMUM_NUMBER_CHANNELS_CARD 1U   // 每张卡最大通道数
#define HART_IO_MAXIMUM_NUMBER_DEVICES_CHANNEL 1U // 每个通道最大设备数
#define HART_IO_MAXIMUM_NUMBER_DELAY_RESPONSE 2U  // 最大延迟响应数
#define HART_IO_MAXIMUM_NUMBER_RETRY_COUNT 3U     // 重试次数
#define HART_IO_PRIMARY_MODE 1U                   // 主模式
#define HART_IO_SECONDARY_MODE 0U                 // 辅助主模式

typedef enum
{
    HART_EEPROM_ADDRESS,
    HART_EEPROM_ADDRESS_USER,
} hart_eeprom_address_e;
// 结束：响应数据域结构

#ifdef STM32
typedef enum
{
    HART_COMMAND_0,   // 读取唯一标识命令
    HART_COMMAND_1,   // 读取主变量
    HART_COMMAND_2,   // 读取回路电流和量程百分比
    HART_COMMAND_3,   // 读取动态变量和回路电流
    HART_COMMAND_6,   // 写入轮训地址
    HART_COMMAND_8,   // 读取动态变量分类
    HART_COMMAND_12,  // 读取消息
    HART_COMMAND_13,  // 读取标签、描述符、日期
    HART_COMMAND_15,  // 读取设备信息
    HART_COMMAND_17,  // 写入消息
    HART_COMMAND_18,  // 写标签、描述符、日期
    HART_COMMAND_20,  // 读取长标签
    HART_COMMAND_21,  // 读取与长标签关联的唯一标识符
    HART_COMMAND_22,  // 写长标签
    HART_COMMAND_38,  // 重置配置更改标志
    HART_COMMAND_48,  // 读取其他设备状态
    HART_COMMAND_33,  // 读取设备变量
    HART_COMMAND_39,  // EEPROM控制
    HART_COMMAND_41,  // 执行自检
    HART_COMMAND_42,  // 执行设备重置
    HART_COMMAND_71,  // 锁定装置
    HART_COMMAND_79,  // 写入设备变量
    HART_COMMAND_89,  // 设置实时时钟
    HART_COMMAND_90,  // 读取实时时钟
    HART_COMMAND_512, // 读取国家代码
    HART_COMMAND_513, // 编写国家代码
    HART_COMMAND_516, // 读取设备位置
    HART_COMMAND_517, // 写入设备位置
    HART_COMMAND_518, // 读取位置说明
    HART_COMMAND_519, // 写入位置说明
    HART_COMMAND_534, // 读取设备变量命令代码

    // 以下自定义
    HART_COMMAND_130, // 自定义参数读取
    HART_COMMAND_131, // 自定义参数设置
    HART_COMMAND_132, // 自定义参数读取(拓展)
    HART_COMMAND_133, // 自定义参数设置(拓展)
    HART_COMMAND_140, // 重置参数
    HART_COMMAND_141, // 设置写入保护
    HART_COMMAND_254, // 数据样品型号(气开\气关)
    HART_COMMAND_255, // 读取模拟量数值
    HART_COMMAND_256, // 读取转化的数值
    HART_COMMAND_257, // 寻找、计算P / I / D
    HART_COMMAND_258, // 计算 摩擦力
    HART_COMMAND_259, // 计算 弹簧力
    HART_COMMAND_260, // 编写参数配置
    HART_COMMAND_261, // 读取参数配置
    HART_COMMAND_500, // 测试指令
    HART_COMMAND_501, // 突发测试数据
    HART_COMMAND_MAX,
} hart_command_e;
#else
// hart命令码定义
/**
 * 命令编号分区
 * 0-30,38,48 普通命令
 * 31 扩展标志
 * 32-121、512-767 通用命令
 * 122-126 仅在现场设备建造期间供工厂使用
 * 128-253 设备特定
 * 127、254-511 保留
 * 768-1023 无线HART
 * 1024-33791 设备系列
 * 33,792-64383 保留
 * 64,384-64511 Discrete
 * 64512-64765  无线设备
 * 64768-65023 附加装置
 * 65024-65535 保留
 */
typedef enum
{
    HART_COMMAND_0 = 0,     // 读取唯一标识命令
    HART_COMMAND_1 = 1,     // 读取主变量
    HART_COMMAND_2 = 2,     // 读取回路电流和量程百分比
    HART_COMMAND_3 = 3,     // 读取动态变量和回路电流
    HART_COMMAND_4 = 4,     // 保留
    HART_COMMAND_5 = 5,     // 保留
    HART_COMMAND_6 = 6,     // 写入轮训地址
    HART_COMMAND_7 = 7,     // 读取循环配置
    HART_COMMAND_8 = 8,     // 读取动态变量分类
    HART_COMMAND_9 = 9,     // 读取具有状态的设备变量
    HART_COMMAND_11 = 11,   // 读取与标签关联的唯一标识符
    HART_COMMAND_12 = 12,   // 读取消息
    HART_COMMAND_13 = 13,   // 读取标签、描述符、日期
    HART_COMMAND_14 = 14,   // 读取主变量传感器信息
    HART_COMMAND_15 = 15,   // 读取设备信息
    HART_COMMAND_16 = 16,   // 读取最终汇编编号
    HART_COMMAND_17 = 17,   // 写入消息
    HART_COMMAND_18 = 18,   // 写标签、描述符、日期
    HART_COMMAND_19 = 19,   // 编写最终汇编号
    HART_COMMAND_20 = 20,   // 读取长标签
    HART_COMMAND_21 = 21,   // 读取与长标签关联的唯一标识符
    HART_COMMAND_22 = 22,   // 写长标签
    HART_COMMAND_38 = 38,   // 重置配置更改标志
    HART_COMMAND_48 = 48,   // 读取其他设备状态
    HART_COMMAND_33 = 33,   // 读取设备变量
    HART_COMMAND_34 = 34,   // 写入主变量阻尼值
    HART_COMMAND_35 = 35,   // 写入主变量范围值
    HART_COMMAND_36 = 36,   // 设置主变量上限值
    HART_COMMAND_37 = 37,   // 设置主变量下限值
    HART_COMMAND_39 = 39,   // EEPROM控制
    HART_COMMAND_40 = 40,   // 进入/退出固定电流模式
    HART_COMMAND_41 = 41,   // 执行自检
    HART_COMMAND_42 = 42,   // 执行设备重置
    HART_COMMAND_43 = 43,   // 设置主变量零
    HART_COMMAND_44 = 44,   // 编写主变量单元
    HART_COMMAND_45 = 45,   // 微调回路电流归零
    HART_COMMAND_46 = 46,   // 微调回路电流增益
    HART_COMMAND_47 = 47,   // 编写主变量传递函数
    HART_COMMAND_49 = 49,   // 写入主变量传感器序列号
    HART_COMMAND_50 = 50,   // 读取动态变量赋值
    HART_COMMAND_51 = 51,   // 编写动态变量赋值
    HART_COMMAND_52 = 52,   // 设置设备变量零
    HART_COMMAND_53 = 53,   // 写入设备变量单元
    HART_COMMAND_54 = 54,   // 读取设备变量信息
    HART_COMMAND_55 = 55,   // 写入设备可变阻尼值
    HART_COMMAND_56 = 56,   // 写入设备可变传感器序列号
    HART_COMMAND_57 = 57,   // 读取单位标签、描述符、日期
    HART_COMMAND_58 = 58,   // 编写单位标签、描述符、日期
    HART_COMMAND_59 = 59,   // 写入响应序码数
    HART_COMMAND_60 = 60,   // 读取模拟通道和范围百分比
    HART_COMMAND_61 = 61,   // 读取动态变量和主变量模拟通道
    HART_COMMAND_62 = 62,   // 读取模拟通道
    HART_COMMAND_63 = 63,   // 读取模拟通道信息
    HART_COMMAND_64 = 64,   // 写入模拟通道附加阻尼值
    HART_COMMAND_65 = 65,   // 写入模拟通道范围值
    HART_COMMAND_66 = 66,   // 进入/退出固定模拟通道模式
    HART_COMMAND_67 = 67,   // 调整模拟通道零
    HART_COMMAND_68 = 68,   // 微调模拟通道增益
    HART_COMMAND_69 = 69,   // 写入模拟通道传递函数
    HART_COMMAND_70 = 70,   // 读取模拟通道端点值
    HART_COMMAND_71 = 71,   // 锁定装置
    HART_COMMAND_72 = 72,   // 呼叫
    HART_COMMAND_73 = 73,   // 查找设备
    HART_COMMAND_74 = 74,   // 读取I/O系统功能
    HART_COMMAND_75 = 75,   // 轮询子设备
    HART_COMMAND_76 = 76,   // 读锁定设备状态
    HART_COMMAND_77 = 77,   // 向子设备发送命令
    HART_COMMAND_78 = 78,   // 读取聚合命令
    HART_COMMAND_79 = 79,   // 写入设备变量
    HART_COMMAND_80 = 80,   // 读取设备可变微调点
    HART_COMMAND_81 = 81,   // 读取设备变量调整指南
    HART_COMMAND_82 = 82,   // 写入设备可变微调点
    HART_COMMAND_83 = 83,   // 重置设备变量调整
    HART_COMMAND_84 = 84,   // 读取子设备标识摘要
    HART_COMMAND_85 = 85,   // 读取I/O通道统计信息
    HART_COMMAND_86 = 86,   // 读取子设备统计信息
    HART_COMMAND_87 = 87,   // 写入I/O系统主模式
    HART_COMMAND_88 = 88,   // 写入I/O系统重试计数
    HART_COMMAND_89 = 89,   // 设置实时时钟
    HART_COMMAND_90 = 90,   // 读取实时时钟
    HART_COMMAND_91 = 91,   // 读取趋势配置
    HART_COMMAND_92 = 92,   // 写入趋势配置
    HART_COMMAND_93 = 93,   // 读取趋势
    HART_COMMAND_94 = 94,   // 读取I/O系统客户端通信统计信息
    HART_COMMAND_95 = 95,   // 读取设备通信统计信息
    HART_COMMAND_96 = 96,   // 读取同步操作
    HART_COMMAND_97 = 97,   // 配置同步操作
    HART_COMMAND_98 = 98,   // 读取命令操作
    HART_COMMAND_99 = 99,   // 配置命令操作
    HART_COMMAND_100 = 100, // 写入主变量报警码
    HART_COMMAND_101 = 101, // 读取子设备到突发消息映射
    HART_COMMAND_102 = 102, // 将子设备映射到突发信息
    HART_COMMAND_103 = 103, // 写入突发周期
    HART_COMMAND_104 = 104, // 写入突发触发器
    HART_COMMAND_105 = 105, // 读取突发模式配置
    HART_COMMAND_106 = 106, // 刷新延迟响应
    HART_COMMAND_107 = 107, // 写入突发设备变量
    HART_COMMAND_108 = 108, // 写入突发模式命令编号
    HART_COMMAND_109 = 109, // 突发模式控制
    HART_COMMAND_110 = 110, // 读取所有动态变量
    HART_COMMAND_111 = 111, // 转移服务控制
    HART_COMMAND_112 = 112, // 传输服务
    HART_COMMAND_113 = 113, // 捕获设备变量
    HART_COMMAND_114 = 114, // 读取捕获的设备变量
    HART_COMMAND_115 = 115, // 读取事件通知摘要
    HART_COMMAND_116 = 116, // 写入事件通知位掩码
    HART_COMMAND_117 = 117, // 写入事件通知时序
    HART_COMMAND_118 = 118, // 事件通知控制
    HART_COMMAND_119 = 119, // 确认事件通知

    // 128-253 设备特定
    HART_COMMAND_130 = 130, // 自定义参数读取
    HART_COMMAND_131 = 131, // 自定义参数设置
    HART_COMMAND_132 = 132, // 自定义参数读取(拓展)
    HART_COMMAND_133 = 133, // 自定义参数设置(拓展)
    HART_COMMAND_140 = 140, // 重置参数
    HART_COMMAND_141 = 141, // 设置写入保护

    // 254-511 自定义指令
    HART_COMMAND_254 = 254, // 数据样品型号(气开\气关)
    HART_COMMAND_255 = 255, // 读取模拟量数值
    HART_COMMAND_256 = 256, // 读取转化的数值
    HART_COMMAND_257 = 257, // 寻找、计算P / I / D
    HART_COMMAND_258 = 258, // 计算 摩擦力
    HART_COMMAND_259 = 259, // 计算 弹簧力
    HART_COMMAND_260 = 260, // 编写参数配置
    HART_COMMAND_261 = 261, // 读取参数配置
    HART_COMMAND_500 = 500, // 测试指令
    HART_COMMAND_501 = 501, // 突发测试数据
    // 自定义指令结束

    HART_COMMAND_512 = 512, // 读取国家代码
    HART_COMMAND_513 = 513, // 编写国家代码
    HART_COMMAND_514 = 514, // 注册事件管理器
    HART_COMMAND_515 = 515, // 读取事件管理器注册状态
    HART_COMMAND_516 = 516, // 读取设备位置
    HART_COMMAND_517 = 517, // 写入设备位置
    HART_COMMAND_518 = 518, // 读取位置说明
    HART_COMMAND_519 = 519, // 写入位置说明
    HART_COMMAND_520 = 520, // 读取进程单元标签
    HART_COMMAND_521 = 521, // 写入进程单元标记
    HART_COMMAND_522 = 522, // 写入体积流分类
    HART_COMMAND_523 = 523, // 读取精简状态映射数组
    HART_COMMAND_524 = 524, // 写入精简状态映射
    HART_COMMAND_525 = 525, // 重置精简状态图
    HART_COMMAND_526 = 526, // 写入状态模拟模式
    HART_COMMAND_527 = 527, // 模拟状态位
    HART_COMMAND_528 = 528, // 读取子设备分配列表信息
    HART_COMMAND_529 = 529, // 读取子设备分配
    HART_COMMAND_530 = 530, // 写入子设备分配
    HART_COMMAND_531 = 531, // 将实时列表传输到分配列表
    HART_COMMAND_532 = 532, // 读取客户端订阅摘要
    HART_COMMAND_533 = 533, // 写入客户端订阅标志
    HART_COMMAND_534 = 534, // 读取设备变量命令代码
    HART_COMMAND_535 = 535, // 写入模拟通道端点值
    HART_COMMAND_536 = 536, // 写入应用时间操作
    HART_COMMAND_537 = 537, // 读取应用时间操作
    HART_COMMAND_538 = 538, // 读取HART-IP服务器端口
    HART_COMMAND_539 = 539, // 写入HART-IP UDP端口
    HART_COMMAND_540 = 540, // 写入HART-IP TCP端口
    HART_COMMAND_541 = 541, // 写入客户端PAKE密码
    HART_COMMAND_542 = 542, // 写入客户端预共享密钥
    HART_COMMAND_543 = 543, // 读取系统日志服务器主机名和端口
    HART_COMMAND_544 = 544, // 写入系统日志端口
    HART_COMMAND_545 = 545, // 写入系统日志服务器主机名
    HART_COMMAND_546 = 546, // 写入系统日志服务器预共享密钥
    HART_COMMAND_547 = 547, // 写入系统日志服务器PAKE密码
    HART_COMMAND_MAX,
} hart_command_e;
// 结束：hart命令码定义
#endif

#pragma pack(1)

// 响应数据域结构
typedef union
{
    uint8_t version;
    struct
    {
        uint8_t physical_signaling_code : 3; // 物理层信号编码
        uint8_t hardware_revision : 5;       // 硬件版本
    } bits;
} device_hardware_revision_u; // 硬件版本

typedef union
{
    uint8_t data;
    struct
    {
        uint8_t frame_type : 3;     // 帧类型，1-突发模式(HART_BURST_FRAME)，2-请求数据(HART_STX_FRAME), 6-应答数据(HART_ACK_FRAME)
        uint8_t physical_layer : 2; // 物理层类型，0-异步，1-同步
        uint8_t ext_bytes : 2;      // 扩展字节数量，0-3
        uint8_t addr_type : 1;      // 地址类型，0-短帧，1-长帧
    } bits;
} hart_delimiter_u; // 定界符

typedef union
{
    uint8_t data;

    struct
    {
        uint8_t slave : 4;    // 从机巡检地址 1-127
        uint8_t reserved : 2; // 第四、五位必须置为0
        uint8_t group : 1;    // 成组模式，0-没有成组，1-从设备处于成组模式
        uint8_t master : 1;   // 主机地址，0-第二主机，1-第一主机
    } bits;
} hart_short_address_u; // 短帧地址格式：共1个字节（8位）

typedef union
{
    uint40_t data;
    struct
    {
        uint8_t reserved : 6;
        uint8_t group : 1;  // 成组模式，0-没有成组，1-从设备处于成组模式
        uint8_t master : 1; // 主机地址，0-第二主机，1-第一主机
        uint8_t slave[4];   // 设备的唯一标识符，共38位。均为0表示广播地址
    } bits;
} hart_long_address_u; // 长帧格式地址：共5个字节（40位）

// hart命令码数据结构定义
typedef struct
{
    uint8_t def;
    uint16_t expanded_device_type;                       // 扩展设备类型
    uint8_t m2s_preambles_limit_count;                   // 主机到从机前导符限制计数
    uint8_t hart_revision;                               // HART协议版本
    uint8_t device_revision;                             // 设备版本
    uint8_t device_software_revision;                    // 设备软件版本
    device_hardware_revision_u device_hardware_revision; // 硬件版本
    uint8_t reserve;                                     // 保留
    uint24_t device_id;                                  // 设备ID，长ID的后3个字节
    // 以下V7版本才有
    uint8_t s2m_response_preambles_count;      // 从机到主机前导符计数
    uint8_t last_device_variable_code;         // 上一个设备变量，这表示应用程序应在现场设备中找到的最后一个设备变量代码（在执行Command 54时读取设备的变量）
    uint16_t configuration_change_counter;     // 配置被更新的次数
    uint8_t extended_device_status;            // 扩展设备状态,未指定的任何位都是未定义的，必须设置为零。
    uint16_t manufacturer_identification_code; // 制造商标识码
    uint16_t private_label_distributor_code;   // 私有标签分销商代码
    uint8_t device_profile;                    // 设备配置文件
} hart_command_0_t;                            // 读取唯一标识命令
typedef struct
{
    uint8_t unit;   // 单位代码
    float32 value;  // 变量值
} hart_command_1_t; // 读取主变量
typedef struct
{
    float32 primary_variable_loop_current;     // 主要回路电流（单位：毫安）
    float32 primary_variable_percent_of_range; // 主要变量量程百分比
} hart_command_2_t;                            // 读取环路电流和量程百分比
typedef struct
{
    float32 primary_variable_loop_current;  // 主要回路电流（单位：毫安）
    uint8_t primary_variable_units_code;    // 主要变量单位代码
    float32 primary_variable;               // 主要变量值
    uint8_t secondary_variable_units_code;  // 次要变量单位代码
    float32 secondary_variable;             // 次要变量值
    uint8_t tertiary_variable_units_code;   // 第三变量单位代码
    float32 tertiary_variable;              // 第三变量值
    uint8_t quaternary_variable_units_code; // 第四变量单位代码
    float32 quaternary_variable;            // 第四变量值
} hart_command_3_t;                         // 读取动态变量和环路电流
typedef struct
{
    uint8_t poll_address; // 设备的轮询地址 V5

    // 以下V7版本才有
    uint8_t loop_current_mode; // 回路电流模式
} hart_command_6_t;            // 写入轮训地址
typedef struct
{
    uint8_t poll_address; // 设备的轮询地址 V5

    // 以下V7版本才有
    uint8_t loop_current_mode; // 回路电流模式
} hart_command_7_t;            // 读取循环配置
typedef struct
{
    uint8_t primary_variable_classification;    // 主要变量分类
    uint8_t secondary_variable_classification;  // 次要变量分类
    uint8_t tertiary_variable_classification;   // 第三变量分类
    uint8_t quaternary_variable_classification; // 第四变量分类
} hart_command_8_t;

typedef struct
{
    uint8_t slot0;
    uint8_t slot1;
    uint8_t slot2;
    uint8_t slot3;
    uint8_t slot4;
    uint8_t slot5;
    uint8_t slot6;
    uint8_t slot7;
} hart_command_9_req_t;

typedef struct
{
    uint8_t code;           // 设备变量代码（参见通用表5.34，设备变量代码表和适当的设备特定文件）
    uint8_t classification; // 设备变量分类（参见通用表5.21）
    uint8_t units_code;     // 单位代码（请参阅通用表格规范5.2）
    float32_u value;        // 设备变量值
    uint8_t status;
} slot_device_variable_rsp_t;
typedef struct
{
    uint8_t extended_field_device_status; // 扩展现场设备状态（参考通用表5.17，扩展现场设备状况）
    slot_device_variable_rsp_t slot[HART_SOLT_DEVICE_VARIABLE_LEN];
    uint32_t slot_data_timestamp; // 插槽0数据时间戳
} hart_command_9_rsp_t;

typedef union
{
    hart_command_9_req_t hart_command_9_req;
    hart_command_9_rsp_t hart_command_9_rsp;
} hart_command_9_t; // 读取具有状态的设备变量

typedef struct
{
    uint8_t tag[HART_PACKED6_LEN]; // 标签
} hart_command_11_t;               // 读取与标签关联的唯一标识符

typedef struct
{
    uint24_t pv_transducer_serial_number;                     // 主要变量传感器序列号
    uint8_t pv_transducer_limits_and_minimum_span_units_code; // 主要变量传感器限制和最小跨度单位代码
    float32_u pv_upper_transducer_limit;                      // 主要变量传感器上限
    float32_u pv_lower_transducer_limit;                      // 主要变量传感器下限
    float32_u pv_minimum_span;                                // 主要变量传感器最小跨度
} hart_command_14_t;                                          // 读取主变量传感器信息

typedef struct
{
    uint8_t pv_alarm_selection_code;                    // 主要变量报警选择代码
    uint8_t pv_transfer_function_code;                  // 主要变量传递函数代码
    uint8_t pv_upper_and_lower_range_values_units_code; // 主要变量上限和下限值单位代码
    float32_u pv_upper_range_value;                     // 主要变量上限值
    float32_u pv_lower_range_value;                     // 主要变量下限值
    float32_u pv_damping_value;                         // 主要变量阻尼值
    uint8_t write_protect_code;                         // 写保护代码
    uint8_t reserved;                                   // 保留,必须设置250
    uint8_t pv_analog_channel_flags;                    // 主要变量模拟通道标志
} hart_command_15_t;                                    // 读取设备信息

typedef struct
{
    uint8_t message[HART_PACKED24_LEN]; // 设备消息24个字节，command17写入，command12读取
} hart_command_17_t;                    // 消息

typedef struct
{
    uint8_t tag[HART_PACKED6_LEN];         // 标签
    uint8_t descriptor[HART_PACKED12_LEN]; // 描述符
    uint8_t date[HART_DATE_LEN];           // 用于记录保存的日期代码
} hart_command_18_t;                       // 标签、描述符、日期

typedef struct
{
    uint8_t final_assembly_number[HART_PACKED3_LEN]; // 总装编号
} hart_command_19_t;

typedef struct
{
    uint8_t long_tag[HART_PACKED32_LEN]; // 长标签
} hart_command_21_t;                     // 读取与标签关联的唯一标识符

typedef struct
{
    uint16_t configuration_change_counter; // 配置被更新的次数
} hart_command_38_t;                       // 重置配置更改标志

typedef struct
{
    uint8_t slot_0; // 插槽0
    uint8_t slot_1; // 插槽1
    uint8_t slot_2; // 插槽2
    uint8_t slot_3; // 插槽3
} hart_command_33_t;

typedef struct
{
    float32 pv_damping_value; // 主要变量阻尼值（以秒为单位）
} hart_command_34_t;

typedef struct
{
    uint8_t pv_upper_and_lower_range_values_units_code; // 主要变量上限值和下限值单位代码
    float32 pv_upper_range_value;                       // 主要变量上限值
    float32 pv_lower_range_value;                       // 主要变量下限值
} hart_command_35_t;

typedef struct
{
    uint8_t control_code; // 0 刻录EEPROM 1 恢复影子内存
} hart_command_39_t;

typedef struct
{
    float32 pv_fixed_current_level;
} hart_command_40_t;

typedef struct
{
    uint8_t pv_units_code; // 主要变量单位代码
} hart_command_44_t;

typedef struct
{
    float32 pv_loop_current_level;
} hart_command_45_t;

typedef struct
{
    float32 pv_loop_current_level;
} hart_command_46_t;

typedef struct
{
    uint8_t pv_transfer_function_code;
} hart_command_47_t;

typedef struct
{
    uint24_t pv_transducer_serial_number;
} hart_command_49_t;

typedef struct
{
    uint8_t device_ariables[4];
} hart_command_51_t;

typedef struct
{
    uint8_t device_ariable;
} hart_command_52_t;

typedef struct
{
    uint8_t device_ariable;           // 设备变量代码
    uint8_t device_ariable_unit_code; // 设备变量单位代码
} hart_command_53_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
} hart_command_54_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
    float32 damping_value;  // 阻尼值（以秒为单位）
} hart_command_55_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
    uint24_t serial_number; // 传感器序列号
} hart_command_56_t;

typedef struct
{
    uint8_t tag[HART_PACKED6_LEN];         // 单位标签6个字节
    uint8_t descriptor[HART_PACKED12_LEN]; // 单位描述符12个字节
    uint8_t date[HART_DATE_LEN];           // 单位日期3个字节
} hart_command_58_t;

typedef struct
{
    uint8_t s2m_preambles; // 从属设备向主设备发送响应消息时要发送的前导码数
} hart_command_59_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
} hart_command_60_t;

typedef struct
{
    uint8_t slot0_analog_channel_number_code; //    插槽0模拟通道编号代码
    uint8_t slot1_analog_channel_number_code; //    插槽1模拟通道编号代码
    uint8_t slot2_analog_channel_number_code; //    插槽2模拟通道编号代码
    uint8_t slot3_analog_channel_number_code; //    插槽3模拟通道编号代码
} hart_command_62_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
} hart_command_63_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
    float32 damping_value;              // 阻尼值（以秒为单位）
} hart_command_64_t;

typedef struct
{
    uint8_t analog_channel_number_code;              // 模拟通道编号代码
    uint8_t upper_and_lower_range_values_units_code; // 上限值和下限值单位代码
    float32 upper_range_value;                       // 上限值
    float32 lower_range_value;                       // 下限值
} hart_command_65_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
    uint8_t units_code;                 // 模拟通道单位代码
    float32 fixed_analog_channel_level; // 固定模拟通道电平
} hart_command_66_t;

typedef struct
{
    uint8_t analog_channel_number_code;  // 模拟通道编号代码
    uint8_t units_code;                  // 模拟通道单位代码
    float32 actual_analog_channel_level; // 实际模拟通道电平
} hart_command_67_t;

typedef struct
{
    uint8_t analog_channel_number_code;               // 模拟通道编号代码
    uint8_t units_code;                               // 模拟通道单位代码
    float32 externally_measured_analog_channel_level; // 外部测量模拟通道电平
} hart_command_68_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
    uint8_t transfer_function_code;     // 模拟通道传递函数代码
} hart_command_69_t;

typedef struct
{
    uint8_t analog_channel_number_code; // 模拟通道编号代码
} hart_command_70_t;

typedef struct
{
    uint8_t lock_code; // 锁定代码
} hart_command_71_t;

typedef struct
{
    uint8_t squawk_control_code; // Squawk控制代码
} hart_command_72_t;

typedef struct
{
    uint8_t card;
    uint8_t channel;
    uint8_t poll_address;
} hart_command_75_t;

typedef struct
{
    uint16_t command;
    uint8_t payload_length;
    uint8_t *command_payload;
} hart_command_78_item_t;
typedef struct
{
    uint8_t count;
    uint8_t *item;
} hart_command_78_t;

typedef struct
{
    uint8_t device_ariable;              // 设备变量代码
    uint8_t device_ariable_command_code; // 设备变量命令代码
    uint8_t device_ariable_unit_code;    // 设备变量单位代码
    float32 device_ariable_value;        // 设备变量值
    uint8_t status;                      // 状态
} hart_command_79_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
} hart_command_80_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
} hart_command_81_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
    uint8_t trim_points;    // 微调点
    uint8_t units_code;     // 单位代码
    float32 value;
} hart_command_82_t;

typedef struct
{
    uint8_t device_ariable; // 设备变量代码
} hart_command_83_t;

typedef struct
{
    uint16_t identifier; // 子设备在IO系统中的索引
} hart_command_84_t;

typedef struct
{
    uint8_t card;    // 卡索引
    uint8_t channel; // 通道索引
} hart_command_85_t;

typedef struct
{
    uint16_t identifier; // 子设备在IO系统中的索引
} hart_command_86_t;

typedef struct
{
    uint8_t master_mode; // 主模式
} hart_command_87_t;

typedef struct
{
    uint8_t retry_count; // 重试计数
} hart_command_88_t;

typedef struct
{
    uint8_t time_set_code;       // 时间集代码
    uint8_t date[HART_DATE_LEN]; // 设置设备实时时钟的日期代码
    uint32_t time;               // 设置设备实时时钟的时间
    uint16_t transmission_time;  // 应设置为0。两个字节，以确保请求和响应占用相等的时间（补偿响应中响应代码和设备状态的传输时间
} hart_command_89_t;

typedef struct
{
    uint8_t trend_number; // 趋势编号
} hart_command_91_t;

typedef struct
{
    uint8_t trend_number;           // 趋势编号
    uint8_t trend_code;             // 趋势控制代码
    uint8_t device_variable_code;   // 设备变量代码
    uint32_t trend_sample_interval; // 趋势样本间隔（最大为2小时：每天一个趋势）
} hart_command_92_t;

typedef struct
{
    uint8_t trend_number; // 趋势编号
} hart_command_93_t;

typedef struct
{
    uint8_t action_number; // 行动编号
} hart_command_96_t;

typedef struct
{
    uint8_t action_number;               // 行动编号
    uint8_t action_control_code;         // 动作控制 synchronization_operation_control_code_e
    uint8_t device_variable_code;        // 设备变量代码。如果操作执行命令，则设备变量代码必须设置为251，“NONE”。 device_variable_code_e
    uint16_t command_number;             // 命令编号。如果操作是对设备变量进行采样，则命令编号必须设置为0xFFFF
    uint8_t trigger_date[HART_DATE_LEN]; // 触发日期
    uint32_t trigger_time;               // 触发时间
} hart_command_97_t;

typedef struct
{
    uint8_t action_number; // 行动编号
} hart_command_98_t;

typedef struct
{
    uint8_t action_number;                                            // 行动编号
    uint16_t command_number;                                          // 命令编号。
    uint8_t command_data_length;                                      // 命令数据长度
    uint8_t command_data[SYNCHRONIZATION_OPERATION_COMMAND_DATA_LEN]; // 命令数据
} hart_command_99_t;

typedef struct
{
    uint8_t pv_alarm_selection_code; // 主要变量报警选择代码 alarms_code_e
} hart_command_100_t;

typedef struct
{
    uint8_t burst_message; // 突发消息
} hart_command_101_t;

typedef struct
{
    uint8_t burst_message;     // 突发消息
    uint16_t sub_device_index; // 子设备索引(索引0表示输入输出系统本身)
} hart_command_102_t;

typedef struct
{
    uint8_t burst_message;           // 突发消息
    uint32_t update_period_time;     // 更新周期为1/32毫秒。更新周期不得超过3600秒
    uint32_t max_update_period_time; // 更新周期为1/32毫秒。更新周期不得超过3600秒
} hart_command_103_t;

typedef struct
{
    uint8_t burst_message;                                    // 突发消息
    uint8_t burst_message_trigger_code;                       // 突发触发模式选择代码 burst_message_trigger_code_e
    uint8_t device_variable_vlassification_for_trigger_level; // 触发电平的设备变量分类 device_variable_classification_code_e
    uint8_t units_code;                                       // 单位代码
    float32 trigger_level;                                    // 触发电平
} hart_command_104_t;

typedef struct
{
    uint8_t burst_message; // 突发消息
} hart_command_105_t;
typedef struct
{
    uint8_t solt_device_variable_codes[HART_DEVICE_VARIABLE_LEN];
    uint8_t burst_message; // 突发消息
} hart_command_107_t;

typedef struct
{
    uint16_t country_code;         // 国家代码
    uint8_t si_units_control_code; // SI单位控制代码
} hart_command_513_t;

typedef struct
{
    uint8_t event_manager_registration_control_code;
} hart_command_514_t;

// 结束：hart命令码数据结构定义

typedef union
{
    hart_command_6_t command_6;     // 写入轮训地址
    hart_command_9_t command_9;     // 读取具有状态的设备变量
    hart_command_11_t command_11;   // 读取与标签关联的唯一标识符
    hart_command_17_t command_17;   // 写入消息
    hart_command_18_t command_18;   // 标签、描述符、日期
    hart_command_19_t command_19;   // 总装编号
    hart_command_21_t command_21;   // 读取与标签关联的唯一标识符
    hart_command_21_t command_22;   // 写长标签
    hart_command_38_t command_38;   // 重置配置更改标志
    hart_command_33_t command_33;   // 读取设备变量
    hart_command_34_t command_34;   // 写入主变量阻尼值
    hart_command_35_t command_35;   // 写入主变量范围值
    hart_command_39_t command_39;   // EEPROM控制
    hart_command_40_t command_40;   // 进入/退出固定电流模式
    hart_command_44_t command_44;   // 编写主变量单元
    hart_command_45_t command_45;   // 微调回路电流归零
    hart_command_46_t command_46;   // 微调回路电流增益
    hart_command_47_t command_47;   // 编写主变量传递函数
    hart_command_49_t command_49;   // 写入主变量传感器序列号
    hart_command_51_t command_51;   // 编写动态变量赋值
    hart_command_52_t command_52;   // 设置设备变量零
    hart_command_53_t command_53;   // 写入设备变量单位
    hart_command_54_t command_54;   // 读取设备变量信息
    hart_command_55_t command_55;   // 写入设备可变阻尼值
    hart_command_56_t command_56;   // 写入设备可变传感器序列号
    hart_command_58_t command_58;   // 编写单位标签、描述符、日期V5
    hart_command_59_t command_59;   // 写入从属设备到主设备响应前导符计数
    hart_command_60_t command_60;   // 写入模拟通道编号代码
    hart_command_62_t command_62;   // 读取模拟通道V5
    hart_command_63_t command_63;   // 读取模拟通道信息V5
    hart_command_64_t command_64;   // 写入模拟通道阻尼值V5
    hart_command_65_t command_65;   // 写入模拟通道上限值和下限值V5
    hart_command_66_t command_66;   // 写入模拟通道固定电平V5
    hart_command_67_t command_67;   // 写入模拟通道实际电平V5
    hart_command_68_t command_68;   // 外部测量模拟通道电平
    hart_command_69_t command_69;   // 写入模拟通道传递函数代码
    hart_command_70_t command_70;   // 读取模拟通道传递函数代码
    hart_command_71_t command_71;   // 写入锁定代码
    hart_command_72_t command_72;   // 写入Squawk控制代码
    hart_command_75_t command_75;   // 轮询子设备
    hart_command_78_t command_78;   // 读取聚合命令(需要动态内存，暂不实现)
    hart_command_79_t command_79;   // 写入设备变量
    hart_command_80_t command_80;   // 读取设备可变微调点
    hart_command_81_t command_81;   // 读取设备变量调整指南
    hart_command_82_t command_82;   // 写入设备可变微调点
    hart_command_83_t command_83;   // 重置设备变量调整
    hart_command_84_t command_84;   // 读取子设备标识摘要
    hart_command_85_t command_85;   // 读取I/O通道统计信息
    hart_command_86_t command_86;   // 读取子设备统计信息
    hart_command_87_t command_87;   // 写入主模式
    hart_command_88_t command_88;   // 写入重试计数
    hart_command_89_t command_89;   // 写入实时时钟
    hart_command_91_t command_91;   // 读取趋势数据
    hart_command_92_t command_92;   // 写入趋势控制
    hart_command_93_t command_93;   // 读取趋势控制
    hart_command_96_t command_96;   // 读取同步操作
    hart_command_97_t command_97;   // 配置同步操作
    hart_command_98_t command_98;   // 读取命令操作
    hart_command_99_t command_99;   // 配置命令操作
    hart_command_100_t command_100; // 写入主要变量报警选择代码
    hart_command_101_t command_101; // 读取子设备到突发消息映射
    hart_command_102_t command_102; // 将子设备映射到突发信息
    hart_command_103_t command_103; // 写入突发周期
    hart_command_104_t command_104; // 写入突发触发器
    hart_command_105_t command_105; // 读取突发模式配置
    hart_command_107_t command_107; // 写入突发设备变量
    hart_command_513_t command_513; // 编写国家代码
    hart_command_514_t command_514; // 注册事件管理器

    // 用户自定义
    hart_user_command_req_data_u;

} hart_command_req_data_u; // HART请求指令数据域

typedef struct
{
    uint8_t delimiter_type;                 // 界定符类型： 0：短帧 1：长帧  默认1
    uint8_t address[HART_LONG_ADDRESS_LEN]; // 短帧地址1个字节，长帧地址5个字节，上位机发送时从低位到高位填充，例如短地址：0x01，长地址：0x00 0x00 0x00 0x00 0x01
    uint32_t command;                       // HART命令码
    hart_command_req_data_u data;           // 数据域

    // 以下解析数据后填充
    uint8_t data_length; // 数据域长度
    uint8_t master;      // 主机地址，0-第二主机，1-第一主机
} hart_command_req_t;    // 主机请求指令接口参数定义:hart_master_command_req

typedef struct
{
    uint64_t uuid;                          // 唯一标识
    uint32_t hart_cache_time;               // hart缓存区寿命
    hart_delimiter_u delimiter;             // 分隔符
    uint8_t address[HART_LONG_ADDRESS_LEN]; // 短帧地址1个字节，长帧地址5个字节，上位机发送时从低位到高位填充，例如短地址：0x01，长地址：0x00 0x00
    uint32_t command;                       // HART命令码
    // private:
    uint8_t command_length; // 命令长度
    uint8_t address_length; // 地址长度

    response_communication_code_e code; // 回复状态码
    uint8_t *payload;
    uint8_t payload_length;
    uint8_t uart_index; // 串口索引
} hart_cache_t;         // 缓存数据结构

typedef struct
{
    uint8_t data[HART_RESPONSE_MAX_LEN]; // 回复数据缓冲区
    uint16_t data_length;                // 回复数据实际长度
    uint8_t *data_p;                     // 回复数据指针
    response_communication_code_e code;  // 回复状态码
    hart_cache_t cache_data;             // 需要缓存的数据
} hart_response_t;                       // 主机和从机回复数据结构

typedef struct
{
    uint8_t alarm_selection_code;                    // 报警选择代码
    uint8_t transfer_function_code;                  // 传递函数代码
    uint8_t upper_and_lower_range_values_units_code; // 上限值和下限值单位代码
    float32 damping_value;                           // 阻尼值（以秒为单位）
    float32 upper_range_value;                       // 上限值
    float32 lower_range_value;                       // 下限值
    uint8_t analog_channel_flags;                    // 模拟通道标志 analog_channel_code_e
} device_attribute_t;                                // 设备属性

typedef struct
{
    uint16_t stx;  // 此设备接收的STX消息计数
    uint16_t ack;  // 从该设备发送的ACK消息计数
    uint16_t back; // 从此设备发送的BACK消息计数
} message_count_t;
typedef struct
{
    uint24_t serial_number;                     // 传感器序列号
    uint8_t limits_and_minimum_span_units_code; // 传感器限制和最小跨度单位代码
    float32_u upper_limit;                      // 传感器上限
    float32_u lower_limit;                      // 传感器下限
    float32_u minimum_span;                     // 传感器最小跨度
} transducer_t;                                 // 传感器
typedef struct
{
    uint8_t trim_points;       // 支持的微调点 trim_points_e
    uint8_t units_code;        // 单位代码
    float32 value;             // 微调点值
    float32 lower;             // 下端点值，单点值
    float32 mini_lower;        // 最小下微调点值（在低微调过程中，仪表不会接受低于此值的值）
    float32 max_lower;         // 最大下微调点值（在低微调过程中，仪表不会接受高于此值的值）
    float32 upper;             // 上端点值
    float32 mini_upper;        // 最小上微调点值（在高微调过程中，仪表不会接受低于此值的值）
    float32 max_upper;         // 最大上微调点值（在高微调过程中，仪表不会接受高于此值的值）
    float32 mini_differential; // 最小差值（上边缘点和下边缘点之间可接受的最小差值）
} trim_point_t;                // 修正点
typedef struct
{
    uint8_t code;                                       // 模拟通道编号代码
    uint8_t units_code;                                 // 模拟通道单位代码
    float32_u level;                                    // 模拟通道电平
    float32_u percent_range;                            // 模拟通道量程百分比
    float32_u fixed_analog_channel_level;               // 固定模拟通道电平  重启后恢复
    float32_u actual_analog_channel_level;              // 下端点值，实际模拟通道电平  重启后恢复
    float32_u externally_measured_analog_channel_level; // 上端点值，外部测量的模拟通道电平  重启后恢复
    device_attribute_t attribute;                       // 设备属性
} analog_channel_t;                                     // 模拟通道
typedef struct
{
    uint8_t code;                               // 设备变量代码 device_variable_code_e
    uint8_t write_device_variable_command_code; // 写入设备变量命令代码  write_device_variable_command_code_e
    uint8_t dynamic_variable_code;              // 动态设备变量,不支持的动态变量返回250（未使用）作为分配的设备变量（ Primary, Secondary, Tertiary, and Quaternary Variables）
    uint8_t classification;                     // 设备变量分类 device_variable_classification_code_e
    uint8_t family;                             // 设备变量家族 device_variable_family_code_e
    uint8_t units_code;                         // 单位代码 transmission_function_code_e
    uint8_t properties;                         // 设备变量属性,默认0，device_variable_property_flags_e
    uint32_t acquisition_period;                // 采集周期,the Acquisition Period indicates the maximum period betweenDevice Variable updates
    __IO float32 *value;                    // 变量值
    device_variable_status_t status;            // 设备变量状态
    device_attribute_t attribute;               // 设备属性
    transducer_t transducer;                    // 传感器
    trim_point_t trim_point;                    // 修正点
    uint8_t alarm_code;                         // 报警代码,报警选择代码表示设备在错误条件下所采取的措施 alarms_code_e
} hart_device_variable_t;                       // 设备变量

typedef struct
{
    uint8_t tag[HART_PACKED6_LEN];         // 单位标签6个字节
    uint8_t descriptor[HART_PACKED12_LEN]; // 单位描述符12个字节
    uint8_t date[HART_DATE_LEN];           // 单位日期3个字节
} unit_device_t;

typedef struct
{
    float32 latitude;  // 纬度(度)正值表示北，负值表示南。绝对值不得大于90.0
    float32 longitude; // 经度(度)正值表示东，负值表示西。绝对值不得大于180.0
    float32 altitude;  // 高于平均海平面的高度(米)。海平面以上数值为正，海平面以下数值为负
    uint8_t location;  // 选址方法/质量 location_method_code_e
} position_t;
typedef struct
{
    uint8_t time_set_code;       // 时间集代码
    uint8_t date[HART_DATE_LEN]; // 设置设备实时时钟的日期代码
    uint32_t time;               // 设置设备实时时钟的时间
    uint16_t transmission_time;  // 应设置为0。两个字节，以确保请求和响应占用相等的时间（补偿响应中响应代码和设备状态的传输时间
    uint8_t rtc_flags;           // 实时时钟标志
} real_time_clock_t;

typedef struct
{
    float32 value;                   // 趋势值
    device_variable_status_t status; // 趋势值状态
} trend_value_t;
typedef struct
{
    uint8_t device_variable_code;           // 设备变量代码 device_variable_code_e
    uint8_t device_variable_classification; // 设备变量分类 device_variable_classification_code_e
    uint8_t device_variable_unit_code;      // 设备变量单位代码 units_code_e
    uint8_t trend_code;                     // 趋势控制代码 trend_control_code_e
    uint32_t trend_sample_interval;         // 趋势样本间隔（最大为2小时：每天一个趋势）

    uint8_t trend_value_date[HART_DATE_LEN]; // 趋势值的日期戳
    uint32_t trend_value_time;               // 趋势值的时间戳
    trend_value_t trend_values[TREND_VALUES_LEN];
} trend_configuration_t; // 趋势配置

typedef struct
{
    uint8_t action_control_code;                                      // 动作控制 synchronization_operation_control_code_e
    uint8_t device_variable_code;                                     // 设备变量代码。如果操作执行命令，则设备变量代码必须设置为251，“NONE”。 device_variable_code_e
    uint16_t command_number;                                          // 命令编号。如果操作是对设备变量进行采样，则命令编号必须设置为0xFFFF
    uint8_t trigger_date[HART_DATE_LEN];                              // 触发日期
    uint32_t trigger_time;                                            // 触发时间
    uint8_t command_data_length;                                      // 命令数据长度
    uint8_t command_data[SYNCHRONIZATION_OPERATION_COMMAND_DATA_LEN]; // 命令数据
} synchronization_operation_t;                                        // 同步操作

typedef struct
{
    uint8_t device_variable_code; // 设备变量代码 device_variable_code_e
} burst_message_slot;
typedef struct
{
    uint32_t update_period_time;                              // 更新周期为1/32毫秒。更新周期不得超过3600秒
    uint32_t max_update_period_time;                          // 更新周期为1/32毫秒。更新周期不得超过3600秒
    float32 trigger_level;                                    // 触发电平
    uint8_t burst_message_trigger_code;                       // 突发触发模式选择代码 burst_message_trigger_code_e
    uint8_t device_variable_vlassification_for_trigger_level; // 触发电平的设备变量分类 device_variable_classification_code_e
    uint8_t units_code;                                       // 单位代码 units_code_e
    uint8_t burst_mode_control_code;                          // 突发模式控制代码 burst_mode_control_code_e
    uint8_t command_number_expansion_flag;                    // 31(0x1F)-命令编号扩展标志  不清楚怎么用
    uint16_t extended_command_number;                         // 扩展命令号
} burst_message_t;                                            // 突发消息

typedef struct
{
    uint8_t poll_address;                            // 设备的轮询地址，地址1个字节
    uint8_t long_address[HART_LONG_ADDRESS_LEN];     // 长帧地址5个字节，上位机发送时从低位到高位填充，例如短地址：0x01，长地址：0x00 0x00 0x00 0x00 0x01
    uint8_t write_protect_code;                      // 写保护代码
    uint8_t message[HART_PACKED32_LEN];              // 设备消息24个字节，command17写入，command12读取
    uint8_t tag[HART_PACKED8_LEN];                   // 标签8个字节
    uint8_t long_tag[HART_PACKED32_LEN];             // 长标签32个字节
    uint8_t descriptor[HART_PACKED16_LEN];           // 描述符16个字节
    uint8_t date[HART_DATE_LEN];                     // 用于记录保存的日期代码3个字节
    uint8_t final_assembly_number[HART_PACKED3_LEN]; // 总装编号3个字节

    uint8_t device_profile;                              // 设备配置文件
    uint8_t device_revision;                             // 设备版本
    uint8_t device_software_revision;                    // 设备软件版本，254,255保留
    uint8_t s2m_preambles;                               // 从设备到主设备的响应前导码个数
    uint16_t extended_device_type;                       // 扩展设备类型
    uint16_t manufacturer_identification_code;           // 制造商标识码
    uint16_t private_label_distributor_code;             // 私有标签分销商代码
    device_hardware_revision_u device_hardware_revision; // 硬件版本
    unit_device_t unit_device;                           // 单位设备

    hart_device_variable_t device_variable[HART_DEVICE_VARIABLE_LEN]; // 设备变量
    analog_channel_t analog_channel[HART_ANALOG_CHANNEL_LEN];         // 模拟通道
    // 以下V7版本才有
    uint16_t country_code;                                                                 // 国家代码
    uint8_t si_units_control_code;                                                         // SI单位控制代码
    uint8_t loop_current_mode;                                                             // 回路电流模式
    uint8_t lock_code;                                                                     // 锁定代码,默认0
    uint8_t event_manager_registration_control_code;                                       // 事件管理器注册控制代码 event_manager_registration_control_code_e
    real_time_clock_t real_time_clock;                                                     // 实时时钟
    trend_configuration_t trend_configurations[TREND_CONFIGURATIONS_LEN];                  // 趋势配置
    synchronization_operation_t synchronization_operations[SYNCHRONIZATION_OPERATION_LEN]; // 同步操作
    burst_message_t burst_messages[BURST_MESSAGE_LEN];                                     // 突发消息
} hart_storage_variable_t;                                                                 // flash变量

typedef struct
{
    uint8_t device_specific_status[6];           // 设备特定状态 device_specific_status_e
    uint8_t extended_device_status;              // 扩展设备状态 extended_device_status_e
    uint8_t device_operating_mode;               // 设备操作模式,所有设备必须在command48读取附加状态中为该字节返回0 operating_mode_codes_e
    uint8_t standardized_status0;                // 标准化状态0 standardized_status0_e
    uint8_t standardized_status1;                // 标准化状态1 standardized_status1_e
    uint8_t analog_channel_saturated;            // 模拟通道饱和 analog_channel_saturated_e
    uint8_t standardized_status2;                // 标准化状态2 standardized_status2_e
    uint8_t standardized_status3;                // 标准化状态3 standardized_status3_e
    uint8_t analog_channel_fixed;                // 固定模拟通道 analog_channel_fixed_e
    uint8_t extended_device_specific_status[11]; // 设备特定状态 device_specific_status_e
} additional_device_status_t;                    // 读取附加设备状态
typedef struct
{
    BOOL reset;                                          // 设备重启标志
    BOOL busy;                                           // 设备自检过程中busy=TRUE，自检结束设置busy=FALSE
    uint8_t operational_state;                           // 设备操作状态 device_operational_state_e，该字段掉电不恢复
    additional_device_status_t additional_device_status; // 附加设备状态
    uint16_t additional_device_status_crc;               // 附加设备状态crc校验码,设备初始化、设备状态也设置完成后，调用接口更新该字段记录设备状态初始值
} hart_device_status_t;                                  // 设备状态,所有状态位都是可选的，未指定的任何位都是未定义的，必须设置为零。

typedef struct
{
    // 这里存放的都是动态变量

    // 这是用户自定义的
    device_variable_dynamics_user_t dynamics_user; // 用户自定义设备变量动态
} device_variable_dynamics_t;                      // 设备变量动态,开发人员对该结构体进行初始化

typedef struct
{
    // 需要实时写入到FLASH中的变量，上电时需要从falsh中读取，在协议中被更新时需要写入到falsh中，地址HART_FALSH_ADDRESS
    hart_storage_variable_t flash_variable;           // flash变量
    hart_storage_variable_user_t flash_variable_user; // 用户自定义flash变量

    // 不需要写入到FLASH中的变量
    uint8_t *hart_protocol_version;     // hart协议版本号
    float32 *actual_pv_current_level;   // 实际PV电流水平，单位毫安
    float32 pv_fixed_current_level;     // 固定电流模式,值为0或设备重启后退出固定电流模式，单位毫安
    float32 pv_loop_current_level;      // 外部测量的PV回路电流水平，单位毫安
    hart_device_status_t device_status; // 设备状态,需要提供接口更新字段

    // 指针映射到flash变量中
    uint8_t *last_device_variable;        // 上一个设备变量，这表示应用程序应在现场设备中找到的最后一个设备变量代码（在执行Command 54时读取设备的变量）
    uint16_t *configuration_update_count; // 配置被更新的次数
    message_count_t message_count;        // 消息计数

    device_variable_dynamics_t dynamics; // 设备变量动态
    int8_t internal;
} hart_device_attribute_t; // 设备属性

#pragma pack()

// 主机属性定义
#pragma pack(1)
typedef struct
{
    uint16_t stx;  // I/O系统在此通道上发送的STX消息的计数
    uint16_t ack;  // 接收到的ACK消息的计数
    uint16_t ostx; // 接收到的OSTX消息的计数（来自其他主机的消息）
    uint16_t oack; // 接收到的OACK消息的计数（对其他主机的答复）
    uint16_t back; // 接收到的BACK消息计数（寻址到任一主机）
} io_system_message_count_t;
typedef struct
{
    uint16_t identifier; // 索引标识符
    BOOL online;         // 在线状态

    uint16_t extended_device_type;     // 扩展设备类型
    uint8_t m2s_preambles_limit_count; // 主设备到从设备的最少同步前导码数量
    uint8_t hart_revision;
    uint8_t device_revision;
    uint8_t device_software_revision;
    device_hardware_revision_u device_hardware_revision;
    uint8_t device_id[3];

    // 以下版本7才有
    uint8_t s2m_preambles;                     // 从设备到主设备的响应前导码个数
    uint8_t last_device_variable;              // 上一个设备变量，这表示应用程序应在现场设备中找到的最后一个设备变量代码（在执行Command 54时读取设备的变量）
    uint16_t configuration_update_count;       // 配置被更新的次数
    uint8_t extended_device_status;            // 扩展设备状态 extended_device_status_e
    uint16_t manufacturer_identification_code; // 制造商标识码
    uint16_t private_label_distributor_code;   // 私有标签分销商代码
    uint8_t device_profile;                    // 设备配置文件
    uint8_t long_tag[HART_PACKED32_LEN];       // 长标签32个字节

    io_system_message_count_t message_count; // 消息计数
} io_system_device_t;

typedef struct
{
    io_system_device_t devices[HART_IO_MAXIMUM_NUMBER_DEVICES_CHANNEL];
    io_system_message_count_t message_count; // 消息计数
} io_system_channel_t;                       // IO系统通道

typedef struct
{
    io_system_channel_t channels[HART_IO_MAXIMUM_NUMBER_CHANNELS_CARD];
} io_system_card_t; // IO系统卡
typedef struct
{
    uint8_t write_protect_code; // 写保护代码
    uint8_t retry_count;        // 重试计数
    uint16_t master_mode;       // 主模式（0=辅助主模式；1=主模式）
    io_system_card_t cards[HART_IO_MAXIMUM_NUMBER_CARDS];
} io_system_t; // IO系统
typedef struct
{
    io_system_t io_system; // IO系统
} hart_master_attribute_t; // 主机属性

#pragma pack()

typedef void (*response_cb)(uint8_t uart_index, uint8_t *data, uint16_t len); // 回复消息接口回调定义
typedef struct
{
    // 主从回复应答消息接口
    response_cb response;
    // 属性初始化
    void (*attribute_init)(void);
    // 自定义属性初始化
    void (*attribute_user_init)(void);
    //  falsh 读写接口
    BOOL(*flash_read)
    (hart_eeprom_address_e addr, uint8_t *data, uint16_t len);

    BOOL(*flash_write)
    (hart_eeprom_address_e addr, uint8_t *data, uint16_t len);

    // 执行自检
    void (*perform_self_test)(void);

    // 设备重置
    void (*device_reset)(void);

    // 设备呼叫,0一直呼叫，1-255秒
    void (*squawk_control)(BOOL open, uint8_t second);

    // 技术人员按下一个特殊的按钮或按钮组合，指示从机应响应command74
    BOOL(*armed)
    (void);

    // 设置动态变量
    BOOL(*set_dynamics)
    (device_variable_dynamics_t *const dynamics);

    // 设置实时时钟
    void (*set_real_time_clock)(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
    void (*get_real_time_clock)(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec);

    // 用户自定义接口
    hart_interface_user_t;
} hart_interface_t;

extern BOOL (*hart_command_ptr_arr[HART_COMMAND_MAX])(const hart_command_req_t *const req, hart_response_t *resp); // 命令处理函数指针数组

extern BOOL hart_storage_write(hart_eeprom_address_e addr, uint8_t *data, uint16_t len);                                 // falsh 读写接口
extern BOOL hart_storage_read(hart_eeprom_address_e addr, uint8_t *data, uint16_t len);                                  // falsh 读写接口
extern void perform_self_test(void);                                                                                     // 执行自检
extern void device_reset(void);                                                                                          // 设备重置
extern void squawk_control(BOOL open, uint8_t second);                                                                   // 设备呼叫,0一直呼叫，1-255秒
extern BOOL armed(void);                                                                                                 // 技术人员按下一个特殊的按钮或按钮组合，指示从机应响应command74
extern void set_real_time_clock(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);       // 设置实时时钟
extern void get_real_time_clock(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec); // 获取实时时钟
extern BOOL user_common_event(hart_interface_user_event_e event, const void *const data);                                // 用户自定义事件

extern uint8_t hart_get_current_protocol_version(void); // 获取当前协议版本
extern BOOL hart_is_support_command(uint16_t command);  // 判断是否支持命令
extern BOOL hart_is_write_command(uint16_t command);    // 判断是否写命令

extern void hart_frame_data_length_start(uint8_t **data_p); // 帧数据长度
extern void hart_frame_data_length_end(uint8_t *data_p);    // 帧数据长度

extern void hart_frame_response_code_start(uint8_t **data_p);                                       // 响应码
extern void hart_frame_response_communication_code(uint8_t code);                                   // 通信响应码
extern void hart_frame_slave_response_operate_code(hart_device_attribute_t *hart_device_attribute); // 从设备响应操作码
extern void hart_frame_master_response_operate_code(void);                                          // 主设备响应操作码

extern uint32_t rtc_to_timestamp(void); // RTC时间转换为时间戳

extern void get_rtc_date(rtc_date_t *date);                                               // 获取RTC时间
extern BOOL is_broadcast_address(uint8_t *address, uint8_t len);                          // 判断是否广播地址
extern void encode_ascii_6(const uint8_t *input, uint16_t input_length, uint8_t *output); // ASCII6编码
extern void decode_ascii_6(const uint8_t *input, uint16_t input_length, uint8_t *output); // ASCII6解码
extern void convert_time(uint32_t t, uint8_t *h, uint8_t *m, uint8_t *s);
extern void convert_timestrap(uint32_t *t, uint8_t h, uint8_t m, uint8_t s, uint16_t ms);
extern void covert_year_rtc(uint8_t *year);

extern void hart_cache_init(void);                  // 缓存消息初始化
extern void hart_cache_add(hart_cache_t data);      // 向缓存中添加数据
extern void hart_cache_free(hart_cache_t *data);    // 释放缓存数据
extern hart_cache_t *hart_cache_get(uint64_t uuid); // 从缓存中获取数据
extern void hart_cache_remove(uint64_t uuid);       // 将指定的uuid对应的数据从缓存区移除
extern void hart_cache_detection(void);             // 检查HART缓存区是否存活
#endif                                              //__HART_FRAME_H_
